<?php

namespace Sharks\Core\Http\Routing;

use Exception;
use Sharks\Core\Exception\RouteResolveException;
use Sharks\Core\Support\Base\DefValue;

/**
 * Url解析结果
 */
class RouteResolveResult {

    private $url;
    private $originalRoute;
    private $verb;

    private $module;
    private $controller;
    private $method;
    private $parameters;

    private $middlewares;

    private $mapResult;

    private $controllerObj;
    private $middlewareObjs;
    
    private $isHit;

    public function __construct(array $with = array()) {
        $this->url =            isset($with['url']) ? $with['url'] : null;
        $this->originalRoute =  isset($with['originalRoute']) ? $with['originalRoute'] : null;
        $this->module =         isset($with['module']) ? $with['module'] : null;
        $this->controller =     isset($with['controller']) ? $with['controller'] : null;
        $this->verb =           isset($with['verb']) ? $with['verb'] : null;
        $this->method =         isset($with['method']) ? $with['method'] : null;
        $this->parameters =     isset($with['parameters']) ? $with['parameters'] : null;
        $this->middlewares =    isset($with['middlewares']) ? $with['middlewares'] : null;
        $this->mapResult =      isset($with['mapResult']) ? $with['mapResult'] : null;
        $this->isHit = true;
    }

    public function __get($name) {
        if ('middlewareObjs' == $name || 'controllerObj' == $name) {
            return $this->$name();
        }
        else {
            return $this->$name;
        }
    }

    public function __set($name, $value) {
        $this->$name = $value;
    }

    /**
     * controller对象
     * @return [type] [description]
     */
    protected function controllerObj() {
        if (is_null($this->controller)) {
            return null;
        }
        return DefValue::isNull($this->controllerObj, function() {
        	try {
                if ('App' == $this->module) {
                    $controllerName = '\\Source\\Http\\Controller\\' . $this->controller . 'Controller';
                }
                else {
                    $controllerName = '\\Sharks\\Module\\' . $this->module . '\\Http\\Controller\\' . $this->controller . 'Controller';
                }
	            $this->controllerObj = new $controllerName;
	        }
	        catch(Exception $e) {
	        	throw new RouteResolveException(sprintf('未找到指定Controller: %s', $this->controller));
	        }
            return $this->controllerObj;
        });
    }

    /**
     * 中间件对象
     * @return [type] [description]
     */
    protected function middlewareObjs() {
        return DefValue::isNull($this->middlewareObjs, function() {
            $this->middlewareObjs = array();
            foreach ($this->middlewares as $alias) {
            	$middleware = RouteControl::getMiddleware($alias);
            	if (empty($middleware)) {
            		throw new RouteResolveException(sprintf('未找到中间件 %s', $middleware));
            	}
                $this->middlewareObjs[] = (new $middleware());
            }
            return $this->middlewareObjs;
        });
    }
}